我們剖析了傳統 SSR/SSG 的運作架構以及 Hydration(水合)的核心意義。今天我們要來探討傳統 SSR 最大的致命傷,以及 React 18 帶來的革命性解方——Streaming SSR 與 Selective/Progressive Hydration(選擇性與漸進式水合)。
在傳統的 SSR 架構中,伺服器與客戶端的互動遵循嚴格的「瀑布流阻塞」:
伺服器端必須完整準備所有資料:必須等到頁面上所有 API 請求都回傳後,伺服器才能開始組裝並輸出 HTML。
客戶端必須下載完所有 JS 才能開始水合:只要有一支龐大的元件 JS 檔還在下載,整個頁面就無法進行水合。
水合主線程阻塞 (Hydration Blocking):當 React 開始在客戶端進行 Hydration 時,它會一口氣同步遍歷整棵 DOM 樹。這段期間如果 VDOM 龐大,主線程會被死死佔用,使用者點擊按鈕或輸入文字將完全沒有反應(看起來畫面能看,但點了沒用)!
React 18 配合 Node.js 的串流傳輸能力,推出了全新 API(如 renderToPipeableStream),徹底打破了「必須等待全部完成才能傳輸」的限制。
串流傳輸 (Streaming HTML)
伺服器可以分段(Chunks)將 HTML 傳送給瀏覽器:
第一步:優先傳送頁面的靜態框架(Shell,如導覽列、側邊欄、載入中 Spinner)。
第二步:當背景的複雜資料準備好後,伺服器再透過同一條 HTTP 連線,將對應的 HTML 片段「串流」推送到瀏覽器中。
結合 <Suspense> 進行非同步拆分
透過 <Suspense> 边界,你可以告訴 React 哪些區塊是次要的、允許延遲載入的:
function App() {
return (
<div>
<NavBar />
{/* 導覽列優先渲染,而 HeavyCommentList 允許在背景非同步載入與串流 */}
<Suspense fallback={<SkeletonLoader />}>
<HeavyCommentList />
</Suspense>
</div>
);
}
傳統 SSR 的水合是「一條鞭」到底;而 React 18 的 Selective Hydration 讓水合過程變得可中斷、可按需調度。
當使用者提前互動時發生什麼事?
假設頁面下方有一塊 HeavyCommentList 還沒完成水合,但使用者提早點擊了該區域的按鈕:
React 捕捉到了使用者的點擊事件。
透過 Fiber 的優先級調度系統,React 會立刻中斷其他區域的水合,優先將使用者點擊的這個組件進行水合(Hydration)。
水合完成後,立刻響應使用者的點擊操作!
這就是漸進式水合 (Progressive Hydration) 的核心魅力:使用者永遠不需要等待整個頁面水合完畢才能互動,哪裡先點,哪裡就先被水合!
Streaming SSR 與 Selective Hydration 完美解決了伺服器輸出與客戶端水合的阻塞問題。而 React 團隊近年推動的終極形態——RSC (React Server Components),更進一步讓「純伺服器端組件」完全不打包進前端 JS Bundle 中,從根本上消除了大型專案的客戶端 JS 體積膨脹問題。